package gw.com.android.ui.onlive.analyst;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.RelativeLayout;
import android.widget.Scroller;

/**
 * 滑的我心态都崩了
 *
 * @author jett
 * @since 2018-06-06.
 */
public class AnalystRootView extends RelativeLayout {

    public AnalystRootView(Context context) {
        super(context);
    }

    public AnalystRootView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public AnalystRootView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    private OnScrollListener listener;
    private Scroller mScroller;
    private int lastX, lastY, direction, mScrolledY, maxScrollY;

    public void setMaxScrollY(int maxScrollY) {
        this.maxScrollY = maxScrollY;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                onEventUp();
                break;
            default:
                break;
        }
        return super.dispatchTouchEvent(event);
    }

    int count = 0;

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                lastX = (int) event.getX();
                lastY = (int) event.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                int mX = (int) event.getX();
                int mY = (int) event.getY();
                int dX = mX - lastX;
                int dY = mY - lastY;
                lastX = mX;
                lastY = mY;
                if (direction == 0) {
                    if (Math.abs(dX) > Math.abs(dY)) {
                        direction = -1;
                    } else if (Math.abs(dY) > Math.abs(dX)) {
                        direction = 1;
                    }
                }
                if (direction == 1 && inScrollRange(dY)) {
                    count++;
                    if (count >= 2) {
                        count = 0;
                        return true;
                    }
                }
                break;
            default:
                break;
        }
        return super.onInterceptTouchEvent(event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_MOVE:
                int mY = (int) event.getY();
                int dY = mY - lastY;
                if (inScrollRange(dY)) {
                    onMove(-dY);
                }
                lastY = mY;
                break;
            default:
                break;
        }
        return super.onTouchEvent(event);
    }

    private void autoExpand() {
        if (mScroller == null) {
            mScroller = new Scroller(getContext());
        }
        int dy = 0 - mScrolledY;
        mScroller.startScroll(0, mScrolledY, 0, dy);
    }

    private void autoShrink() {
        if (mScroller == null) {
            mScroller = new Scroller(getContext());
        }
        int dy = maxScrollY - mScrolledY;
        mScroller.startScroll(0, mScrolledY, 0, dy);
    }

    @Override
    public void computeScroll() {
        super.computeScroll();
        if (mScroller != null && mScroller.computeScrollOffset()) {
            mScrolledY = mScroller.getCurrY();
            if (listener != null) {
                float percent = mScrolledY * 1.0F / maxScrollY;
                listener.onScrolled(-1, mScrolledY, maxScrollY, percent);
            }
            postInvalidate();
        }
    }

    private void onMove(int distance) {
        mScrolledY += distance;
        if (mScrolledY > maxScrollY) {
            mScrolledY = maxScrollY;
        } else if (mScrolledY < 0) {
            mScrolledY = 0;
        }
        if (listener != null) {
            float percent = mScrolledY * 1.0F / maxScrollY;
            listener.onScrolled(distance, mScrolledY, maxScrollY, percent);
        }
    }

    private void onEventUp() {
        direction = 0;
        if (mScrolledY > 0 && mScrolledY < maxScrollY) {
            if (mScrolledY >= maxScrollY / 2) {
                autoShrink();
            } else {
                autoExpand();
            }
            postInvalidate();
        }
    }

    private boolean inScrollRange(int distance) {
        if (distance > 0 && mScrolledY > 0) {
            return true;
        } else if (distance < 0 && mScrolledY < maxScrollY) {
            return true;
        }
        return false;
    }

    public void setOnScrollListener(OnScrollListener listener) {
        this.listener = listener;
    }

    public interface OnScrollListener {
        void onScrolled(int distance, int scrolled, int max, float percent);
    }

}
